package com.sky.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.Task.WebSocketServer;
import com.sky.context.BaseContext;
import com.sky.dto.*;
import com.sky.entity.AddressBook;
import com.sky.entity.OrderDetail;
import com.sky.entity.Orders;
import com.sky.entity.ShoppingCart;
import com.sky.exception.AddressBookBusinessException;
import com.sky.exception.OrderBusinessException;
import com.sky.exception.ShoppingCartBusinessException;
import com.sky.mapper.AddressBookMapper;
import com.sky.mapper.OrderDetailMapper;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.ShoppingCartMapper;
import com.sky.result.PageResult;
import com.sky.service.OrderService;
import com.sky.vo.OrderStatisticsVO;
import com.sky.vo.OrderSubmitVO;
import com.sky.vo.OrderVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.sky.constant.MessageConstant.*;

@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    OrderMapper orderMapper;
    @Autowired
    OrderDetailMapper orderDetailMapper;
    @Autowired
    AddressBookMapper addressBookMapper;
    @Autowired
    ShoppingCartMapper shoppingCartMapper;
    @Autowired
    WebSocketServer webSocketServer;

    @Override
    @Transactional
    public OrderSubmitVO submitOrder(OrdersSubmitDTO ordersSubmitDTO) {
//        先校验一下各种异常
//        第一,收货地址不能为空
        AddressBook addressBook = addressBookMapper.get(ordersSubmitDTO.getAddressBookId());
        if (addressBook == null || addressBook.getDetail() == null || addressBook.getDetail().isEmpty()) {
            throw new AddressBookBusinessException(ADDRESS_BOOK_IS_NULL);
        }
//        System.out.println("收货地址正常");
//        第二,购物车不能为空
        List<ShoppingCart> shoppingCarts = shoppingCartMapper.seleteByUserId(BaseContext.getCurrentId());
        if (shoppingCarts == null || shoppingCarts.isEmpty()) {
            throw new ShoppingCartBusinessException(SHOPPING_CART_IS_NULL);
        }
//        System.out.println("购物车正常");
//        用户下单,订单表添加一条数据
        Orders order = new Orders();
        BeanUtils.copyProperties(ordersSubmitDTO, order);
        order.setOrderTime(LocalDateTime.now());
        order.setPayStatus(Orders.UN_PAID);
        order.setStatus(Orders.PENDING_PAYMENT);
        order.setNumber(String.valueOf(System.currentTimeMillis()) + BaseContext.getCurrentId());
        order.setPhone(addressBook.getPhone());
        order.setConsignee(addressBook.getConsignee());
        order.setUserId(BaseContext.getCurrentId());
        Long id = orderMapper.insert(order);
//        System.out.println("插入订单正常");
//        每张订单会包含多个菜品或者套餐,需要往订单明细表插入多条数据
        List<OrderDetail> orderDetailList = new ArrayList<>();
        shoppingCarts.forEach(shoppingCart -> {
            OrderDetail orderDetail = new OrderDetail();
            BeanUtils.copyProperties(shoppingCart, orderDetail);
            orderDetail.setOrderId(order.getId());
            orderDetailList.add(orderDetail);
//            System.out.println(orderDetail);
        });
        orderDetailMapper.insertBatch(orderDetailList);
//        System.out.println("插入订单明细正常");
//        用户下单之后购物车记得清空
        shoppingCartMapper.clean(BaseContext.getCurrentId());
//        System.out.println("清空购物车正常");
//        最后封装返回结果
        OrderSubmitVO orderSubmitVO = new OrderSubmitVO();
        orderSubmitVO.setId(id);
        orderSubmitVO.setOrderTime(order.getOrderTime());
        orderSubmitVO.setOrderNumber(order.getNumber());
        orderSubmitVO.setOrderAmount(order.getAmount());
        return orderSubmitVO;
    }

    @Override
    public void payOrder(OrdersPaymentDTO ordersPaymentDTO) {
        Long id = BaseContext.getCurrentId();
        Map map = new HashMap();
        map.put("type", 1);
        map.put("orderId", ordersPaymentDTO.getOrderNumber());
        map.put("content", "来新的订单了哦~");
        String s = JSON.toJSONString(map);
        webSocketServer.sendToAllClient(s);
        orderDetailMapper.updateStatus(ordersPaymentDTO.getOrderNumber());
    }

    @Override
    public PageResult historyOrders(int page, int pageSize, Integer status) {
//        先拿到这个用户的id
        Long id = BaseContext.getCurrentId();
        PageHelper.startPage(page, pageSize);
        OrdersPageQueryDTO ordersPageQueryDTO = new OrdersPageQueryDTO();
        ordersPageQueryDTO.setStatus(status);
        ordersPageQueryDTO.setUserId(id);
        Page<Orders> page1 = orderMapper.pageQuery(ordersPageQueryDTO);
        List<OrderVO> list = new ArrayList<>();
//        查询订单详情,然后封装进ordervo进行相应
        if (page1 != null && !page1.isEmpty()) {
            for (Orders orders : page1) {
                Long id1 = orders.getId();
//                使用订单号查询订单明细
                List<OrderDetail> orderDetails = orderDetailMapper.getByOrderId(id1);
                OrderVO orderVO = new OrderVO();
                BeanUtils.copyProperties(orders, orderVO);
                orderVO.setOrderDetailList(orderDetails);
                list.add(orderVO);
            }
        }
        System.out.println(333);
        if (page1 != null) {
            return new PageResult(page1.getTotal(), list);
        }
        return null;
    }

    @Override
    public OrderVO detail(Long id) {
        Orders orders = orderMapper.getById(id);
        if (orders != null) {
            List<OrderDetail> orderDetails = orderDetailMapper.getByOrderId(id);
            OrderVO orderVO = new OrderVO();
            BeanUtils.copyProperties(orders, orderVO);
            orderVO.setOrderDetailList(orderDetails);
            return orderVO;
        }
        return null;
    }

    @Override
    public void cancel(Long id) {
//        根据订单的不同状态,取消订单分为这几种情况
//        1代付款 2待接单 3已接单 4派送中 5已完成 6已取消
//        先把订单查出来
        Orders orders = orderMapper.getById(id);
        if (orders == null) throw new OrderBusinessException(ORDER_NOT_FOUND);
//        如果订单已经接单了,得用户打电话沟通,所以,状态大于2就直接报错
        if (orders.getStatus() > 2) throw new OrderBusinessException(ORDER_STATUS_ERROR);
//        不仅需要修改订单状态为已取消,而且需要写入取消时间和取消原因
        orders.setStatus(6);
        orders.setCancelTime(LocalDateTime.now());
        orders.setCancelReason("用户取消订单");
        orderMapper.update(orders);

    }

    @Override
    public void repetition(Long id) {

//        先用id把原来的订单和订单详情查出来
//        然后购买一样的订单就好
//查询用户id
        Long userid = BaseContext.getCurrentId();
        id = orderMapper.getById(id).getId();
        List<OrderDetail> orderDetailList = orderDetailMapper.getByOrderId(id);
//        System.out.println(id);
//        把订单详情转化成购物车对象
        List<ShoppingCart> shoppingCarts = orderDetailList.stream().map(x -> {
            ShoppingCart shoppingCart = new ShoppingCart();
            BeanUtils.copyProperties(x, shoppingCart, "id");
            shoppingCart.setUserId(userid);
            shoppingCart.setCreateTime(LocalDateTime.now());
            return shoppingCart;
        }).collect(Collectors.toList());

//        然后再批量插入数据库
        shoppingCartMapper.insertBatch(shoppingCarts);
    }

    @Override
    public PageResult conditionSearch(OrdersPageQueryDTO ordersPageQueryDTO) {
        PageHelper.startPage(ordersPageQueryDTO.getPage(), ordersPageQueryDTO.getPageSize());
        Page<Orders> page = orderMapper.pageQuery(ordersPageQueryDTO);
        List<OrderVO> list = new ArrayList<>();
        List<Orders> ordersList = page.getResult();
        if (ordersList != null && !ordersList.isEmpty()) {
            for (Orders orders : ordersList) {
                OrderVO orderVO = new OrderVO();
                BeanUtils.copyProperties(orders, orderVO);
                String orderDosjes = getOrderDishesStr(orders);
                orderVO.setOrderDishes(orderDosjes);
                list.add(orderVO);
            }
        }
        if (page != null) {
            return new PageResult(page.getTotal(), list);
        }
        return null;

    }

    private String getOrderDishesStr(Orders orders) {
        List<OrderDetail> orderDetailList = orderDetailMapper.getByOrderId(orders.getId());
        List<String> list = orderDetailList.stream().map(x -> {
            String tmp = x.getName() + "*" + x.getNumber();
            return tmp;
        }).collect(Collectors.toList());
        return String.join(",", list);
    }

    @Override
    public OrderStatisticsVO statistics() {
        Integer toBeConfirmed = orderMapper.countstatus(Orders.TO_BE_CONFIRMED);
        Integer confirmed = orderMapper.countstatus(Orders.CONFIRMED);
        Integer deliveryInProgress = orderMapper.countstatus(Orders.DELIVERY_IN_PROGRESS);
        return OrderStatisticsVO.builder().toBeConfirmed(toBeConfirmed).confirmed(confirmed).deliveryInProgress(deliveryInProgress).build();
    }

    @Override
    public void confirm(OrdersConfirmDTO ordersConfirmDTO) {
        Orders orders = Orders.builder().id(ordersConfirmDTO.getId()).status(Orders.CONFIRMED).build();
        orderMapper.update(orders);

    }

    @Override
    public void rejection(OrdersRejectionDTO ordersRejectionDTO) {
        Orders orderMapperById = orderMapper.getById(ordersRejectionDTO.getId());
        if (orderMapperById == null || !orderMapperById.getStatus().equals(Orders.TO_BE_CONFIRMED))
            throw new OrderBusinessException(ORDER_STATUS_ERROR);
        Orders orders = Orders.builder().id(ordersRejectionDTO.getId()).status(Orders.CANCELLED).cancelReason(ordersRejectionDTO.getRejectionReason()).cancelTime(LocalDateTime.now()).build();
        orderMapper.update(orders);
    }

    @Override
    public void Scancel(OrdersCancelDTO ordersCancelDTO) {
        Orders orders = orderMapper.getById(ordersCancelDTO.getId());
        orders.setCancelReason(ordersCancelDTO.getCancelReason());
        orders.setCancelTime(LocalDateTime.now());
        orders.setStatus(Orders.CANCELLED);
        orderMapper.update(orders);
    }

    @Override
    public void develivery(Long id) {
        Orders orders = orderMapper.getById(id);
        if (!Objects.equals(orders.getStatus(), Orders.CONFIRMED)) throw new OrderBusinessException(ORDER_STATUS_ERROR);
        orders.setStatus(Orders.DELIVERY_IN_PROGRESS);
        orderMapper.update(orders);
    }

    @Override
    public void complete(Long id) {
        Orders orders = orderMapper.getById(id);
        if (!Objects.equals(orders.getStatus(), Orders.DELIVERY_IN_PROGRESS))
            throw new OrderBusinessException(ORDER_STATUS_ERROR);
        orders.setStatus(Orders.COMPLETED);
        orders.setDeliveryTime(LocalDateTime.now());
        orderMapper.update(orders);
    }

    @Override
    public void reminder(Long id) {
//        看看有没有这个订单
        Orders orders = orderMapper.getById(id);
        if (orders == null) throw new OrderBusinessException(ORDER_STATUS_ERROR);
        Map map = new HashMap();
        map.put("type", 2);
        map.put("orderId", id);
        map.put("content", "订单号:" + orders.getNumber());
        webSocketServer.sendToAllClient(JSON.toJSONString(map));
    }

}
